# tts_player.py
import asyncio
import tempfile
import simpleaudio as sa
from pydub import AudioSegment
import edge_tts


class TextToSpeech:
    def __init__(self,
                 voice="zh-CN-XiaoxiaoNeural",
                 rate="+0%",
                 volume="+0%"):
        """
        :param voice: 语音名称，可以换别的中文女声/男声
        :param rate: 语速，例："+10%", "-20%"
        :param volume: 音量，例："+0%", "+20%"
        """
        self.voice = voice
        self.rate = rate
        self.volume = volume

    async def _synthesize_to_file(self, text: str, out_path: str):
        communicate = edge_tts.Communicate(
            text=text,
            voice=self.voice,
            rate=self.rate,
            volume=self.volume,
        )
        await communicate.save(out_path)

    def speak(self, text: str, block: bool = True):
        """
        文本转语音并播放
        :param text: 要朗读的文本
        :param block: True 表示播放完才返回，False 表示异步播放
        """
        # 1. 先异步合成到临时文件
        with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f:
            tmp_path = f.name

        asyncio.run(self._synthesize_to_file(text, tmp_path))

        # 2. 读入音频并播放
        audio = AudioSegment.from_file(tmp_path, format="mp3")
        raw_data = audio.raw_data
        sample_rate = audio.frame_rate
        num_channels = audio.channels
        bytes_per_sample = audio.sample_width

        play_obj = sa.play_buffer(
            raw_data,
            num_channels=num_channels,
            bytes_per_sample=bytes_per_sample,
            sample_rate=sample_rate,
        )

        if block:
            play_obj.wait_done()
        # 不删临时文件也问题不大，体积很小；要删可以额外加 os.remove(tmp_path)
